/*
 * hashTests.cpp
 *
 *  Created on: Oct 16, 2012
 *      Author: Federico Orquera
 */

#include <iostream>
#include <memory>

#include "HashRecord.h"
#include "HashBucket.h"
//#include "HashBucketCache.h"
#include "HashFile.h"
#include "archivoDirecto.h"

//Tests registro
#define test1id 	0
#define test1autor 	"Federico"
#define test1frase 	"Hola Mundo"
#define test2id 	1
#define test2autor 	"Mariano"
#define test2frase 	"Chau Mundo"
#define test3id		2
#define test3autor	"Pedro"
#define test3frase 	"Pablito Clavo Un Clavito"

//Tests Cubeta
#define test1td 	2

using namespace std;

int main(){

	cout<<endl<<"Testeando HashRecord"<<endl;
	HashRecord testRegistro1(test1id,test1autor,test1frase);
	cout<<"\t getId() "	<<(((testRegistro1.getId()==test1id)==1)?"OK":"FAIL")<<endl;
	cout<<"\t getAutor() "	<<(((testRegistro1.getAutorApellido()==test1autor)==1)?"OK":"FAIL")<<endl;
	cout<<"\t getFrase() "	<<(((testRegistro1.getFrase()==test1frase)==1)?"OK":"FAIL")<<endl;

	cout<<endl<<"Testeando HashBucket"<<endl;
	HashBucket testCubeta1, testCubeta2, testCubeta3(5);
	cout<<"\t getBucketNr() "<<endl;
	cout<<"\t NroCubeta is defineable "<<((testCubeta3.getBucketNr()==5)?"OK":"FAIL")<<endl;
	cout<<"\t NroCubeta is unique "<<(((testCubeta1.getBucketNr() != testCubeta2.getBucketNr())==1)?"OK":"FAIL")<<endl;
	cout<<"\t isFull() "			<<((testCubeta1.isFull()==false)?"OK":"FAIL")<<endl;
	cout<<"\t setTd() & getTd()";
	testCubeta1.setTd(test1td);
	cout<<(((testCubeta1.getTd()==test1td)==1)?"OK":"FAIL")<<endl;
	cout<<"\t getCount() "<<((testCubeta1.getCount()==0)?"OK":"FAIL")<<endl;
	cout<<"\t addRecord() ";
	testCubeta1.addRegister(test1id,test1autor,test1frase);
	testCubeta1.addRegister(test2id,test2autor,test2frase);
	cout<<((testCubeta1.getCount()==2)?"OK":"FAIL")<<endl;
	cout<<"\t getRecord() "<<((testCubeta1.getRecord(test1id)->getId()==test1id)?"OK":"FAIL")<<endl;
	cout<<"\t getRecordByIndex() "<<((testCubeta1.getRecordByIndex(1)->getId()==test2id)?"OK":"FAIL")<<endl;
	cout<<"\t recordExists() "<<((testCubeta1.recordExists(test2id))?"OK":"FAIL")<<endl;
	cout<<"\t deleteRecordByIndex() ";
	testCubeta1.deleteRecordByIndex(0);
	cout<<((testCubeta1.recordExists(test1id))?"FAIL":"OK")<<endl;
	cout<<"\t resetBucket() ";
	testCubeta1.resetBucket();
	cout<<((testCubeta1.getCount()==0)?"OK":"FAIL")<<endl;

	cout<<endl<<"Testeando HashFile"<<endl;

	HashFile testHashFile1;
	cout<<"\t getNumberOfBuckets() "	<<((testHashFile1.getNumberOfBuckets()==0)?"OK":"FAIL")<<endl;

	cout<<"\t getNewBucket() ";
	bucket_ptr testSharedPTR1;
	testSharedPTR1 = testHashFile1.getNewBucket();
	cout<<((testSharedPTR1->isFull()==false)?"OK":"FAIL")<<endl;

	cout<<"\t getBucket() ";
	bucket_ptr testSharedPTR2;
	testSharedPTR2 = testHashFile1.getBucket(testSharedPTR1->getBucketNr());
	cout<<((testSharedPTR1->getBucketNr()==testSharedPTR2->getBucketNr())?"OK":"FAIL")<<endl;

	cout<<"\t getBucket() with non existent number ";
	try {

		unsigned int new_index = testSharedPTR1->getBucketNr() + 1;

		testHashFile1.getBucket(new_index);
	}
	catch( HashFileExceptions exception ) {
		cout<<( (exception == HashFileExceptions::BUCKET_DOES_NOT_EXIST )?"OK":"FAIL" )<<endl;
	}

	cout<<"\t freeBucket() ";
	testSharedPTR2 = testHashFile1.getNewBucket();
	unsigned int antes = testHashFile1.getNumberOfBuckets();
	testHashFile1.freeBucket(testSharedPTR2->getBucketNr());
	unsigned int despues = testHashFile1.getNumberOfBuckets();
	cout<<( ( antes == despues+1 )?"OK":"FAIL" )<<endl;

	cout<<endl<<"Testeando Hash"<<endl;
	ArchivoDirecto testHash1;
	cout<<"\t getNroCubetas() "		<<((testHash1.getNroCubetas()==1)?"OK":"FAIL")<<endl;
	cout<<"\t Insertando primer registro "			<<(testHash1.addRecord(test1id,test1autor,test1frase)?"OK":"FAIL")<<endl;
	cout<<"\t Insertando nuevo registro, no unico "	<<(testHash1.addRecord(test1id,test1autor,test1frase)?"FAIL":"OK")<<endl;
	cout<<"\t Insertando nuevo registro, unico "	<<(testHash1.addRecord(test2id,test2autor,test2frase)?"OK":"FAIL")<<endl;

	cout<<"\t Multiples registros unicos"	<<endl;
	cout<<"\t Insertando registro "<<test2id+1<<endl;
	testHash1.addRecord(test2id+1,test1autor,test1frase);
	cout<<"\t Insertando registro "<<test2id+2<<endl;
	testHash1.addRecord(test2id+2,test2autor,test2frase);
	cout<<"\t Insertando registro "<<test2id+3<<endl;
	testHash1.addRecord(test2id+3,test1autor,test2frase);
	cout<<"\t Insertando registro "<<test2id+4<<endl;
	testHash1.addRecord(test2id+4,test2autor,test2frase);
	cout<<"\t Insertando registro "<<test2id+5<<endl;
	testHash1.addRecord(test2id+5,test2autor,test2frase);
	testHash1.listarContenido();

	cout<<"\t Eliminando Registro invalido "<<test2id+6<<" ";
	try {
		testHash1.removeRecord(test2id+6);
	}
	catch( ArchivoDirectoExceptions exception ) {
		cout<<( (exception == ArchivoDirectoExceptions::RECORD_NUMBER_IS_INVALID )?"OK":"FAIL" )<<endl;
	}

	cout<<"\t Eliminando Registro valido "<<test1id<<endl;
	testHash1.removeRecord(test1id);
	testHash1.listarContenido();

	cout<<"\t Modificando registro "<<test3id<<endl;
	testHash1.modificarRegistro(test3id,test3autor,test3frase);
	testHash1.listarContenido();

	cout<<endl;
	return 0;
}
